﻿using System;
using System.Text;
using System.Web.Security;
using log4net;
using Matrix.MaKaYunShang.BLL.CacheActionService;
using Matrix.MaKaYunShang.Model;
using Matrix.MaKaYunShang.Model.MatrixCloudApi;
using Matrix.MaKaYunShang.Model.Wechat;
using Matrix.Common.Utility;
using Newtonsoft.Json;

namespace Matrix.MaKaYunShang.BLL.WxInterfaceFunc
{
    /// <summary>
    /// 微信接口基础类
    /// </summary>
    public class BaseWxInterFunc
    {
        private readonly ILog _fileLog = LogManager.GetLogger(typeof(BaseWxInterFunc));


        #region 网络请求方法
        /// <summary>
        /// GET方式请求
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string GetHttpsInterfaceWebContent(string url)
        {
            var strJson = ClientHelper.GetWebContent(url);
            if (string.IsNullOrWhiteSpace(strJson))
                throw new WxErrorMsgException("The result value of interface is empty",
                    WxErrorMsgExceptionType.CloudCustomerException);

            if (strJson.Contains("\"errcode\":") && strJson.Contains("\"errmsg\":"))
            {
                throw new WxErrorMsgException(strJson, WxErrorMsgExceptionType.WxErrorException);
            }

            return strJson;
        }

        /// <summary>
        /// POST方式请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="postData"></param>
        /// <returns></returns>
        public static string PostHttpsInterfaceWebContent(string url, string postData)
        {
            string strErrMsg;
            var strJson = ClientHelper.PostWeb(url, postData, Encoding.UTF8, out strErrMsg);
            if (!string.IsNullOrWhiteSpace(strErrMsg))
            {
                throw new Exception(strErrMsg);
            }

            if (string.IsNullOrWhiteSpace(strJson))
                throw new WxErrorMsgException("The result value of interface is empty",
                    WxErrorMsgExceptionType.CloudCustomerException);

            //if (strJson.Contains("\"errcode\":") && strJson.Contains("\"errmsg\":"))
            //{
            //    throw new WxErrorMsgException(strJson, WxErrorMsgExceptionType.WxErrorException);
            //}

            return strJson;
        }

        /// <summary>
        /// POST方式请求，并指定CONTENT_TYPE
        /// </summary>
        /// <param name="url"></param>
        /// <param name="postData"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static string PostHttpsInterfaceWebContent(string url, byte[] postData, string contentType = null)
        {
            if (string.IsNullOrWhiteSpace(contentType))
            {
                contentType = "application/Json";
            }

            string strErrMsg;
            var strJson = ClientHelper.PostWeb(url, postData, Encoding.UTF8, contentType, out strErrMsg);
            if (!string.IsNullOrWhiteSpace(strErrMsg))
            {
                throw new Exception(strErrMsg);
            }

            if (string.IsNullOrWhiteSpace(strJson))
                throw new WxErrorMsgException("The result value of interface is empty",
                    WxErrorMsgExceptionType.CloudCustomerException);

            if (strJson.Contains("\"errcode\":") && strJson.Contains("\"errmsg\":"))
            {
                throw new WxErrorMsgException(strJson, WxErrorMsgExceptionType.WxErrorException);
            }

            return strJson;
        }
        
        /// <summary>
        /// POST方式请求，并制定文件路径
        /// </summary>
        /// <param name="url"></param>
        /// <param name="filepath"></param>
        /// <returns></returns>
        public static string PostHttpsInterfaceWebContentWithFilePath(string url, string filepath)
        {
            string strErrMsg;
            var strJson = ClientHelper.PostWeb(url, filepath, out strErrMsg);
            if (!string.IsNullOrWhiteSpace(strErrMsg))
            {
                throw new Exception(strErrMsg);
            }

            if (string.IsNullOrWhiteSpace(strJson))
                throw new WxErrorMsgException("The result value of interface is empty",
                    WxErrorMsgExceptionType.CloudCustomerException);

            if (strJson.Contains("\"errcode\":") && strJson.Contains("\"errmsg\":"))
            {
                throw new WxErrorMsgException(strJson, WxErrorMsgExceptionType.WxErrorException);
            }

            return strJson;
        }

        /// <summary>
        /// POST方式请求，不检查ERRCODE
        /// </summary>
        /// <param name="url"></param>
        /// <param name="postData"></param>
        /// <returns></returns>
        public static string PostHttpsInterfaceWebContentIgnorErrCode(string url, string postData)
        {
            string strErrMsg;
            var strJson = ClientHelper.PostWeb(url, postData, Encoding.UTF8, out strErrMsg);
            if (!string.IsNullOrWhiteSpace(strErrMsg))
            {
                throw new Exception(strErrMsg);
            }

            if (string.IsNullOrWhiteSpace(strJson))
                throw new WxErrorMsgException("The result value of interface is empty",
                    WxErrorMsgExceptionType.CloudCustomerException);

            return strJson;
        }
        #endregion

        #region 微信时间工具
        public DateTime? FormatToTime(string createTime)
        {
            try
            {
                var lCreateTime = long.Parse(createTime);
                var lCreateTimeMSecond = lCreateTime * 1000L;//java长整型日期，毫秒为单位                
                var dtStartPoint = new DateTime(1970, 1, 1, 0, 0, 0);
                var ticksStartPoint = dtStartPoint.Ticks;//1970年1月1日刻度                         
                var ticksAll = ticksStartPoint + lCreateTimeMSecond * 10000;//日志日期刻度                         
                var dt = new DateTime(ticksAll).AddHours(8);//转化为DateTime
                return dt;
            }
            catch
            {
                return null;
            }

        }

        public long FormatToWxTime(DateTime createTime)
        {
            var standardCreateTime = createTime.AddHours(-8);
            var dtStartPoint = new DateTime(1970, 1, 1, 0, 0, 0);
            var lWxCreateTImeMSecond = (standardCreateTime.Ticks - dtStartPoint.Ticks) / 10000L;
            var lWxCreateTime = lWxCreateTImeMSecond / 1000L;
            return lWxCreateTime;

        }
        #endregion

        #region 文件接口
        /// <summary>
        /// 上传图片接口
        /// </summary>
        /// <returns></returns>
        /// <remarks>上传的图片限制文件大小限制1MB，像素为300*300，仅支持JPG、PNG格式</remarks>
        /// <remarks>调用接口获取的logo_url仅支持在微信相关业务下使用</remarks>
        public string UploadCardImageToWechatServer(string accessToken, string filepath)
        {
            if (string.IsNullOrWhiteSpace(accessToken) || string.IsNullOrWhiteSpace(filepath))
            {
                _fileLog.Info("BaseWxInterFunc | UploadCardImageToWechatServer : The parameter is empty.");
                return string.Empty;
            }

            const string strInterfaceUrl =
                "https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={0}";
            var strRequestUrl = string.Format(strInterfaceUrl, accessToken);

            var strJson = PostHttpsInterfaceWebContentWithFilePath(strRequestUrl, filepath);

            if (string.IsNullOrWhiteSpace(strJson)) return null;

            var dictImagUrl = JsonLib.DataRowFromJson(strJson);

            return dictImagUrl["url"].ToString();
        }

        /// <summary>
        /// 上传下载多媒体文件
        /// </summary>
        /// <param name="accessToken"></param>
        /// <param name="filepath"></param>
        /// <param name="mediaType"></param>
        /// <returns></returns>
        public WeChatUploadMediaResult UploadMeidaFileToWechatServer(string accessToken, string filepath,
            MxApiWechatMediaFileType mediaType)
        {
            if (string.IsNullOrWhiteSpace(accessToken) || string.IsNullOrWhiteSpace(filepath))
            {
                _fileLog.Error("BaseWxInterFunc | UploadCardImageToWechatServer : The parameter is empty.");
                return null;
            }

            const string strInterfaceUrl =
                "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={0}&type={1}";
            var strRequestUrl = string.Format(strInterfaceUrl, accessToken, mediaType.ToString().ToLower());

            var strJson = PostHttpsInterfaceWebContentWithFilePath(strRequestUrl, filepath);

            if (string.IsNullOrWhiteSpace(strJson)) return null;

            return JsonConvert.DeserializeObject<WeChatUploadMediaResult>(strJson);
        }

        #endregion

        #region 验证微信签名
        /// <summary>  
        /// 验证微信签名  
        /// </summary>  
        /// * 将token、timestamp、nonce三个参数进行字典序排序  
        /// * 将三个参数字符串拼接成一个字符串进行sha1加密  
        /// * 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信。  
        /// <returns></returns>  
        public bool ValidateSignature(string signature, string timestamp, string nonce, string signatureToken)
        {
            string[] arrTmp = { signatureToken, timestamp, nonce };
            Array.Sort(arrTmp);     //字典排序  
            var tmpStr = string.Join("", arrTmp);
#pragma warning disable 618
            tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
#pragma warning restore 618
            if (tmpStr == null) return false;
            tmpStr = tmpStr.ToLower();
            return tmpStr == signature;
        }
        #endregion
    }
}
